#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "server.h"
#include <sys/types.h>

// 服务器的构造函数
struct Server server_Constructor(int domain, int port, int service, int protocol, int backlog, u_long interface, void (*launch)(struct Server *server))
{
    struct Server server;         // 定义服务器结构体，作为返回值
    server.domain = domain;       // 定义服务器的地域，如果是IPV4就填AF_INET
    server.service = service;     // 服务器的服务号，一般分为sock_stream和sock_dgram
    server.port = port;           // 服务器的端口号
    server.protocol = protocol;   // 协议号，用于socket函数，一般填0，代表默认协议
    server.backlog = backlog;     // 监听数量，作用是在指定服务器在拒绝连接之前，允许积压的最大连接请求数
    server.interface = interface; // 服务器的IP地址，一般填INADDR_ANY

    server.address.sin_family = domain;                // 填充服务器里面的sockaddr_in结构体的sin_family成员，AF_INET
    server.address.sin_port = htons(port);             // 填充服务器里面的sockaddr_in结构体的sin_port成员，端口号
    server.address.sin_addr.s_addr = htonl(interface); // 填充服务器里面的sockaddr_in结构体的sin_addr成员，IP地址

    server.socket = socket(domain, service, protocol); // 创建服务器套接字
    if (server.socket < 0)                             // 服务器套接字创建失败
    {
        perror("Failed to initialize/connect to socket...\n");
        exit(EXIT_FAILURE);
    }
    if (bind(server.socket, (struct sockaddr *)&server.address, sizeof(server.address)) < 0) // 服务器的套接字绑定失败
    {
        perror("Failed to bind socket...\n");
        exit(EXIT_FAILURE);
    }
    if (listen(server.socket, server.backlog) < 0) // 监听服务器的套接字失败
    {
        perror("Failed to start listening...\n");
        exit(EXIT_FAILURE);
    }
    server.launch = launch; // 服务器启动之后，要执行的任务（此处为HTTP服务器）
    return server;
}

// 服务器启动函数，参数需要一个服务器结构体
void launch(struct Server *server)
{
    char buffer[BUFFER_SIZE]; // 定义了一个接受缓冲区，用于从套接字中接受数据
    while (1)
    {
        printf("=== WAITING FOR CONNECTION === \n");
        int addrlen = sizeof(server->address);
        int new_socket = accept(server->socket, (struct sockaddr *)&(server->address), (socklen_t *)&addrlen); // 客户端套接字
        ssize_t byteRead = read(new_socket, buffer, BUFFER_SIZE - 1);                                          // 从客户端套接字中接收数据，并且read函数返回接受的数据总数
        if (byteRead >= 0)                                                                                     // 如果接收的数据大于0（成功接受了数据）
        {
            buffer[byteRead] = '\0'; // 在接收数据的末尾加上‘0’，作为字符串的结尾
            puts(buffer);            // 向终端打印接收到的数据
        }
        else // 小于0，代表接收数据失败
        {
            perror("Error reading buffer...\n");
        }
        char *response = "HTTP/1.1 200 OK\r\n" // http响应字段
                         "Content-Type: text/html; charset=UTF-8\r\n\r\n"
                         "<!DOCTYPE html>\r\n"
                         "<html>\r\n"
                         "<head>\r\n"
                         "<title>Testing Basic HTTP-SERVER</title>\r\n"
                         "</head>\r\n"
                         "<body>\r\n"
                         "Hello, Ahmed!\r\n"
                         "</body>\r\n"
                         "</html>\r\n";
        write(new_socket, response, strlen(response)); // 发回http响应
        close(new_socket);                             // 关闭客户端套接字
    }
}